#include <stdio.h>
#include <math.h>
#include "../app.h"
#include "../font/font.h"
#include "dvc.h"

typedef struct infos
{
    const char *const name;
    lv_align_t align;
    lv_coord_t pct_x;
    lv_coord_t pct_y;
    lv_color_t bg_color;
    lv_color_t color;
    const char *const unit;
} afe_infos_t;

static const afe_infos_t infos_map[] = {
    {"电压", LV_ALIGN_TOP_LEFT, 0, 0, LV_COLOR_MAKE(81, 170, 92), LV_COLOR_MAKE(255, 255, 255), "V"},
    {"电流", LV_ALIGN_TOP_RIGHT, 0, 0, LV_COLOR_MAKE(0, 164, 231), LV_COLOR_MAKE(255, 255, 255), "A"},
    {"功率", LV_ALIGN_BOTTOM_LEFT, 0, 0, LV_COLOR_MAKE(98, 106, 239), LV_COLOR_MAKE(255, 255, 255), "W"},
    {"剩余容量", LV_ALIGN_BOTTOM_RIGHT, 0, 0, LV_COLOR_MAKE(0, 0, 0), LV_COLOR_MAKE(255, 255, 255), "AH"},
    // {"剩余容量", LV_ALIGN_BOTTOM_RIGHT, 0, 0, LV_COLOR_MAKE(165, 149, 254), LV_COLOR_MAKE(255, 255, 255), "AH"},
};

#define AFE_INFOS_SIZE (sizeof(infos_map) / sizeof(infos_map[0]))

extern dvc_t gloab_dvc;
static lv_obj_t *numer_objs[AFE_INFOS_SIZE] = {0};
static uint32_t last_voltage = 0;

static void timer_task_cb(struct _lv_timer_t *timer)
{
    if (!gloab_dvc)
        return;

    float *datas[AFE_INFOS_SIZE] = {
        &gloab_dvc->voltage,
        &gloab_dvc->current,
        &gloab_dvc->power,
        &gloab_dvc->coulomb_counter.bat_rmA,
    };

    uint8_t r_percentage = (uint8_t)(gloab_dvc->coulomb_counter.bat_rmA / gloab_dvc->coulomb_counter.bat_mA * 100);

    for (uint8_t i = 0; i < AFE_INFOS_SIZE; i++)
    {
        if (!numer_objs[i])
            continue;
        int32_t value = 0;
        if (i == 0)
        {
            value = *datas[i] * 1000;
            last_voltage += value;
            last_voltage /= 2;
            // value = LowPassFilterOperator(&vol_filter, *datas[i]) * 1000;
            lv_label_set_text_fmt(numer_objs[i], "%lu.%03lu %s", last_voltage / 1000, last_voltage % 1000, infos_map[i].unit);
            last_voltage = value;
        }
        else if (i < 3)
        {
            static const char *const c_units[] = {"A", "mA", "uA"};
            static const char *const p_units[] = {"W", "mW", "uW"};

            float tmp = fabs(*datas[i]);
            uint8_t idx = 0;
            while (tmp < 1.0f)
            {
                tmp *= 1000.0f;
                idx++;
                if (idx >= (sizeof(c_units) / sizeof(c_units[0]) - 1))
                    break;
            }

            value = tmp * 100;
            if (*datas[i] >= 0.000000f)
                lv_label_set_text_fmt(numer_objs[i], "%lu.%02lu %s", value / 100, value % 100, i == 1 ? c_units[idx] : p_units[idx]);
            else
                lv_label_set_text_fmt(numer_objs[i], "-%lu.%02lu %s", value / 100, value % 100, i == 1 ? c_units[idx] : p_units[idx]);
        }
        else
        {
            lv_obj_t *progress = lv_obj_get_child(timer->user_data, 0);
            lv_obj_t *progress_bar = lv_obj_get_child(progress, 0);
            lv_obj_t *progress_label = lv_obj_get_child(progress, 1);
            lv_obj_set_width(progress_bar, lv_pct(r_percentage));
            lv_label_set_text_fmt(progress_label, "%u", r_percentage);

            value = *datas[i] / 3.6 / 1000;
            lv_label_set_text_fmt(numer_objs[i], "%lu.%02lu %s", value / 1000, value % 1000, infos_map[i].unit);
        }
        lv_obj_align(numer_objs[i], LV_ALIGN_BOTTOM_MID, 0, 10);
    }
}
lv_timer_t *app_afe_info_create(lv_obj_t *parent, uint8_t id)
{
    if (!parent)
        return NULL;
    static const uint8_t con_size = 100 / (AFE_INFOS_SIZE / 2) - AFE_INFOS_SIZE / 2 - 1;

    lv_obj_t *obj = lv_tileview_add_tile(parent, id, 0, LV_DIR_HOR);
    lv_obj_set_style_pad_all(obj, 10, LV_PART_MAIN);
    lv_obj_set_style_text_font(obj, base_font18, LV_PART_MAIN);
    lv_obj_set_style_bg_color(obj, lv_color_make(0, 0, 0), LV_PART_MAIN);

    lv_obj_t *progress = lv_obj_create(obj);
    lv_obj_set_size(progress, LV_PCT(con_size), LV_PCT(con_size));
    lv_obj_set_style_pad_all(progress, 0, LV_PART_MAIN);
    lv_obj_set_style_border_width(progress, 1, LV_PART_MAIN);
    lv_obj_set_style_bg_opa(progress, LV_OPA_80, LV_PART_MAIN);
    lv_obj_set_style_bg_color(progress, lv_color_make(0, 0, 0), LV_PART_MAIN);
    lv_obj_set_style_border_color(progress, lv_color_make(46, 213, 115), LV_PART_MAIN);

    lv_obj_t *progress_bar = lv_obj_create(progress);
    lv_obj_align(progress_bar, LV_ALIGN_RIGHT_MID, 0, 0);
    lv_obj_set_size(progress_bar, LV_PCT(50), LV_PCT(100));
    lv_obj_set_style_border_width(progress_bar, 0, LV_PART_MAIN);
    lv_obj_set_style_bg_opa(progress_bar, LV_OPA_80, LV_PART_MAIN);
    lv_obj_set_style_bg_color(progress_bar, lv_color_make(46, 213, 115), LV_PART_MAIN);

    lv_obj_t *progress_label = lv_label_create(progress);
    lv_obj_align(progress_label, LV_ALIGN_TOP_RIGHT, 0, 3);
    lv_label_set_text(progress_label, "50");
    lv_obj_set_style_text_color(progress_label, lv_color_make(255, 255, 255), LV_PART_MAIN);

    for (uint8_t i = 0; i < AFE_INFOS_SIZE; i++)
    {
        /* main */
        lv_obj_t *tmp = lv_obj_create(obj);
        lv_obj_set_scroll_dir(tmp, LV_DIR_NONE); /* 不允许滑动 - 没用触摸 - 禁用滑动条 */
        lv_obj_set_size(tmp, LV_PCT(con_size), LV_PCT(con_size));
        lv_obj_align(tmp, infos_map[i].align, infos_map[i].pct_x, infos_map[i].pct_x);
        lv_obj_set_style_border_width(tmp, 0, LV_PART_MAIN);
        lv_obj_set_style_bg_color(tmp, infos_map[i].bg_color, LV_PART_MAIN);
        lv_obj_set_style_text_color(tmp, infos_map[i].color, LV_PART_MAIN);
        lv_obj_set_style_bg_opa(tmp, LV_OPA_50, LV_PART_MAIN);
        /* title */
        lv_obj_t *title = lv_label_create(tmp);
        lv_label_set_text_static(title, infos_map[i].name);
        lv_obj_align(title, LV_ALIGN_TOP_LEFT, -8, -10);
        /* Content */
        lv_obj_t *number = lv_label_create(tmp);
        lv_label_set_text_fmt(number, "00.00 %s", infos_map[i].unit);
        lv_obj_align(number, LV_ALIGN_BOTTOM_MID, 0, 10);
        numer_objs[i] = number;
    }

    lv_obj_align_to(progress, lv_obj_get_child(obj, 4), LV_ALIGN_CENTER, 0, 0);

    lv_timer_t *timer = lv_timer_create(timer_task_cb, 1000, obj);
    lv_timer_pause(timer);
    return timer;
}

app_s afe_info_page = {
    .name = "afe_info",
    .create = app_afe_info_create,
    .delete = NULL,
    .update = NULL,
    .user_data = NULL,
};
